package handler

import (
	"context"
	"encoding/json"
	"exam-app/exam-srv/global"
	"exam-app/exam-srv/internal/model/dao"
	"exam-app/exam-srv/internal/model/service"
	pb "exam-app/exam-srv/proto"
	"fmt"
	"time"
)

type ExamServer struct {
	pb.UnimplementedExamServer
}

// 试题的新增
func (e *ExamServer) Create(ctx context.Context, req *pb.CreateRequest) (resp *pb.CreateResponse, err error) {

	//查询父id是否存在
	pid := service.GetExamPid(int(req.Pid))
	if !pid {
		return nil, fmt.Errorf("父级id不存在")
	}
	subject := dao.Subjects{
		SubjectClassification: req.SubjectClassification,
		TitleClassification:   int(req.TitleClassification),
		Title:                 req.Title,
		Option:                int(req.Option),
		Difficulty:            int(req.Difficulty),
		Pid:                   int(req.Pid),
	}
	if err = global.DB.Create(&subject).Error; err != nil {
		return nil, fmt.Errorf("试题新增失败")
	}
	return &pb.CreateResponse{Message: "试题新增成功"}, nil
}

// 分类查询
func (e *ExamServer) Category(ctx context.Context, req *pb.CategoryRequest) (resp *pb.CategoryResponse, err error) {

	var subjects []dao.Subjects
	if err = global.DB.Where("pid = ?", req.Pid).Find(&subjects).Error; err != nil {
		return nil, fmt.Errorf("查询分类失败")
	}
	var slice []*pb.Subject
	for _, subject := range subjects {
		slice = append(slice, &pb.Subject{
			SubjectClassification: subject.SubjectClassification,
			TitleClassification:   int32(subject.TitleClassification),
			Title:                 subject.Title,
			Option:                int32(subject.Option),
			Difficulty:            int32(subject.Difficulty),
			Pid:                   int32(subject.Pid),
		})
	}

	return &pb.CategoryResponse{Category: slice}, nil
}

func (e *ExamServer) TextAdd(ctx context.Context, req *pb.TextAddRequest) (resp *pb.TextAddResponse, err error) {

	text := dao.TestPaper{
		Status:             int(req.Status),
		TestName:           req.Name,
		TestClassification: int(req.TestClassification),
		Random:             int(req.Random),
		Num:                int(req.Num),
		Or:                 int(req.Or),
		UserId:             int(req.UserId),
	}
	if err = global.DB.Create(&text).Error; err != nil {
		return nil, fmt.Errorf("考题添加失败")
	}

	return &pb.TextAddResponse{Message: "考题添加成功"}, nil
}
func (e *ExamServer) TextUpdate(ctx context.Context, req *pb.TextUpdateRequest) (resp *pb.TextUpdateResponse, err error) {

	var text dao.TestPaper
	if err = global.DB.Where("id = ?", req.Id).First(&text).Error; err != nil {
		return nil, fmt.Errorf("考题不存在")
	}
	text.Status = int(req.Status)
	text.TestName = req.Name
	text.TestClassification = int(req.TestClassification)
	text.Random = int(req.Random)
	text.Num = int(req.Num)
	text.Or = int(req.Or)
	if err = global.DB.Save(&text).Error; err != nil {
		return nil, fmt.Errorf("修改失败")
	}
	return &pb.TextUpdateResponse{Message: "考题修改成功"}, nil
}
func (e *ExamServer) Update(ctx context.Context, req *pb.UpdateRequest) (resp *pb.UpdateResponse, err error) {

	var subjects dao.Subjects
	if err = global.DB.Where("id = ?", req.Id).First(&subjects).Error; err != nil {
		return nil, fmt.Errorf("考题不存在")
	}
	subjects.SubjectClassification = req.SubjectClassification
	subjects.TitleClassification = int(req.TitleClassification)
	subjects.Title = req.Title
	subjects.Option = int(req.Option)
	subjects.Difficulty = int(req.Difficulty)

	if err = global.DB.Save(&subjects).Error; err != nil {
		return nil, fmt.Errorf("修改失败")
	}
	return &pb.UpdateResponse{Message: "修改成功"}, nil
}

func (e *ExamServer) Del(ctx context.Context, req *pb.DelRequest) (resp *pb.DelResponse, err error) {

	var subjects dao.Subjects
	if err = global.DB.Where("id = ?", req.Id).Delete(&subjects).Error; err != nil {
		return nil, fmt.Errorf("删除失败")
	}
	return &pb.DelResponse{Message: "删除成功"}, nil
}
func (e *ExamServer) TextCreate(ctx context.Context, req *pb.TextCreateRequest) (resp *pb.TextCreateResponse, err error) {

	var subjects []dao.Subjects
	if err = global.DB.Find(&subjects).Error; err != nil {
		return nil, fmt.Errorf("试题列表展示失败")
	}
	tx := global.DB.Begin()
	for _, subject := range subjects {
		text := dao.TestPaper{
			Status:             int(req.Status),
			TestName:           req.Name,
			TestClassification: int(req.TestClassification),
			Random:             int(req.Random),
			Num:                int(req.Num),
			Or:                 int(req.Or),
			UserId:             int(req.UserId),
			SubjectID:          int(subject.ID),
		}
		if err = global.DB.Create(&text).Error; err != nil {
			return nil, fmt.Errorf("试卷发布失败")
		}
		tx.Rollback()
	}
	tx.Commit()
	return &pb.TextCreateResponse{Message: "试卷发布成功"}, nil
}
func (e *ExamServer) TextDel(ctx context.Context, req *pb.TextDelRequest) (resp *pb.Empty, err error) {

	var text dao.TestPaper
	if err = global.DB.Where("id = ?", req.Id).Delete(&text).Error; err != nil {
		return nil, fmt.Errorf("删除失败")
	}
	return &pb.Empty{Message: "删除试卷成功"}, nil
}

func (e *ExamServer) TextList(ctx context.Context, req *pb.TextListRequest) (resp *pb.TextListResponse, err error) {

	var text []dao.TestPaper
	if err = global.DB.Where("status = 1").Find(&text).Error; err != nil {
		return nil, fmt.Errorf("查询失败")
	}
	marshal, err := json.Marshal(text)
	if err != nil {
		return nil, fmt.Errorf("序列化失败")
	}
	err = global.Rdb.Set("key", marshal, time.Minute*10).Err()
	if err != nil {
		return nil, err
	}
	var slice []*pb.Text
	err = json.Unmarshal(marshal, &slice)
	if err != nil {
		return nil, err
	}

	for _, b := range slice {
		slice = append(slice, &pb.Text{
			Status:             b.Status,
			Name:               b.Name,
			TestClassification: b.TestClassification,
			Random:             b.Random,
			Num:                b.Num,
			Or:                 b.Or,
		})
	}
	return &pb.TextListResponse{List: slice}, nil
}

func (e *ExamServer) Timer(ctx context.Context, req *pb.TimerRequest) (resp *pb.TimerResponse, err error) {

	// 3.timer实现延时的功能
	time.Sleep(time.Second)
	timer3 := time.NewTimer(10 * time.Minute)
	<-timer3.C
	fmt.Println("10分钟到")
	return &pb.TimerResponse{}, nil
}
func (e *ExamServer) TextShow(ctx context.Context, req *pb.TextShowRequest) (resp *pb.TextShowResponse, err error) {

	var text []dao.TestPaper
	if err = global.DB.Where("id  = ?", req.Id).First(&text).Error; err != nil {
		return nil, fmt.Errorf("详情展示失败")
	}
	var slice []*pb.Show
	for _, v := range text {
		slice = append(slice, &pb.Show{
			CreateAt:           v.CreatedAt.String(),
			Status:             int32(v.Status),
			Name:               v.TestName,
			TestClassification: int32(v.TestClassification),
			Random:             int32(v.Random),
			Num:                int32(v.Num),
			Or:                 int32(v.Or),
		})
	}
	return &pb.TextShowResponse{
		List: slice,
	}, nil
}

func (e *ExamServer) Rank(ctx context.Context, req *pb.RankRequest) (resp *pb.RankResponse, err error) {

	result, err := global.Rdb.ZRevRangeWithScores("rank", 0, 9).Result()
	if err != nil {
		return nil, err
	}
	var slice []*pb.Rank
	for _, z := range result {
		slice = append(slice, &pb.Rank{
			Name:  z.Member.(string),
			Score: float32(z.Score),
		})
	}
	return &pb.RankResponse{Rank: slice}, nil
}
